package com.ler.action.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ler.action.entity.MavenJsonBean;
import com.ler.action.entity.MavenJsonBean.DependencyBean;
import com.ler.action.entity.MavenJsonBean.DependencyBean.ExclusionsBean;
import com.ler.action.entity.MavenJsonBean.DependencyBean.ExclusionsBean.ExclusionBean;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author lww
 * @date 2020-05-27 17:07
 */
public class GradleParser {

    private final static Pattern GROUP_PB = Pattern.compile("(?<=group:)(.)+(?=, name)");
    private final static Pattern NAME_PB = Pattern.compile("(?<=name:)(.)+(?=, version)");
    private final static Pattern VERSION_PB = Pattern.compile("(?<=version:)(.)+");
    private final static Pattern EX_GROUP_PB = Pattern.compile("(?<=group:)(.)+(?=, module)");
    private final static Pattern MODEL_PB = Pattern.compile("(?<=module:)(.)+");

    public static MavenJsonBean parseGradle(String data) {
        MavenJsonBean bean = new MavenJsonBean();
        DependencyBean dependencyBean = new DependencyBean();
        ExclusionsBean exclusionsBean = new ExclusionsBean();
        List<ExclusionBean> exclusion = new ArrayList<>();

        bean.setDependency(dependencyBean);
        dependencyBean.setExclusions(exclusionsBean);
        exclusionsBean.setExclusion(exclusion);
        boolean testCompile = data.contains("testCompile");
        if (data.contains("{")) {
            String[] split = data.split("\\{");
            easyParser(split[0], dependencyBean);
            String ex = split[1];
            Matcher exGroupMatcher = EX_GROUP_PB.matcher(ex);
            Matcher modelMatcher = MODEL_PB.matcher(ex);
            while (exGroupMatcher.find() && modelMatcher.find()) {
                ExclusionBean exclusionBean = new ExclusionBean();
                exclusionBean.setGroupId(exGroupMatcher.group().replaceAll("'", "").replaceAll("\"", "").trim());
                exclusionBean.setArtifactId(modelMatcher.group().replaceAll("'", "").replaceAll("\"", "").trim());
                exclusion.add(exclusionBean);
            }
        } else {
            easyParser(data, dependencyBean);
        }
        return bean;
    }

    private static void easyParser(String data, DependencyBean dependency) {
        if (data.contains("group")) {
            Matcher groupMatcher = GROUP_PB.matcher(data);
            if (groupMatcher.find()) {
                String group = groupMatcher.group();
                dependency.setGroupId(group.replaceAll("'", "").replaceAll("\"", "").replaceAll("\\(", "").replaceAll("\\)", "").trim());
            }
            Matcher nameMatcher = NAME_PB.matcher(data);
            if (nameMatcher.find()) {
                String name = nameMatcher.group();
                dependency.setArtifactId(name.replaceAll("'", "").replaceAll("\"", "").replaceAll("\\(", "").replaceAll("\\)", "").trim());
            }
            Matcher versionMatcher = VERSION_PB.matcher(data);
            if (versionMatcher.find()) {
                String version = versionMatcher.group();
                dependency.setVersion(version.replaceAll("'", "").replaceAll("\"", "").replaceAll("\\(", "").replaceAll("\\)", "").trim());
            }
        } else {
            //compile "com.sbt:hr-api:0.2.5-SNAPSHOT"
            String compile = data.replaceAll("compile", "").replaceAll("\\(", "").replaceAll("\\)", "").replaceAll("\"", "");
            String[] split = compile.split(":");
            dependency.setGroupId(split[0].trim());
            dependency.setArtifactId(split[1].trim());
            if (split.length > 2) {
                dependency.setVersion(split[2].trim());
            }
        }
    }

    /**
     * Json to xml string.
     *
     * @param json the json
     * @return the string
     */
    public static String jsonToXml(String json) {
        try {
            StringBuffer buffer = new StringBuffer();
            JSONObject jObj = JSON.parseObject(json);
            String xmlstr = json2Xmlstr(jObj, buffer);
            return buffer.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * Json to xmlstr string.
     *
     * @param jObj   the j obj
     * @param buffer the buffer
     * @return the string
     */
    private static String json2Xmlstr(JSONObject jObj, StringBuffer buffer) {
        Set<Map.Entry<String, Object>> se = jObj.entrySet();
        for (Entry<String, Object> en : se) {
            if ("com.alibaba.fastjson.JSONObject".equals(en.getValue().getClass().getName())) {
                buffer.append("<").append(en.getKey()).append(">");
                JSONObject jo = jObj.getJSONObject(en.getKey());
                json2Xmlstr(jo, buffer);
                buffer.append("</").append(en.getKey()).append(">");
            } else if ("com.alibaba.fastjson.JSONArray".equals(en.getValue().getClass().getName())) {
                JSONArray jarray = jObj.getJSONArray(en.getKey());
                for (int i = 0; i < jarray.size(); i++) {
                    buffer.append("<").append(en.getKey()).append(">");
                    JSONObject jsonobject = jarray.getJSONObject(i);
                    json2Xmlstr(jsonobject, buffer);
                    buffer.append("</").append(en.getKey()).append(">");
                }
            } else if ("java.lang.String".equals(en.getValue().getClass().getName())) {
                buffer.append("<").append(en.getKey()).append(">").append(en.getValue());
                buffer.append("</").append(en.getKey()).append(">");
            }
        }
        return buffer.toString();
    }

}
